home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / macgambit-20-compiler-src-p1 / Runtime (.c & .h) / os_mac_Print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-26  |  12.5 KB  |  463 lines  |  [TEXT/KAHL]

  1. /* os_mac_Print.c */
  2. /* 28Sep92  e     */
  3. /* adapted from ...
  4. /*
  5. ** Apple Macintosh Developer Technical Support
  6. **
  7. ** Program:     MacShell
  8. ** File:        print.c
  9. ** Written by:  Eric Soldan
  10. ** Based on:    Code from Pete "Luke" Alexander.
  11. **
  12. ** Copyright © 1989-1991 Apple Computer, Inc.
  13. ** All rights reserved.
  14. */
  15.  
  16. /* portions Copyright © 1992 e.  All rights reserved. */
  17.  
  18. /*****************************************************************************/
  19.  
  20. /* 28Sep92  e  edited for Gambit */
  21.  
  22. #ifdef THINK_C
  23. #if THINK_C < 5
  24. #define THINK_PRE_5
  25. #endif
  26. #endif
  27.  
  28. #include "os_mac_eEdit.h"
  29.  
  30. #include <Packages.h>
  31.  
  32. #define rPrStatusDlg (270)
  33.  
  34. #ifndef __ERRORS__
  35. #include <Errors.h>
  36. #endif
  37.  
  38. #ifndef __RESOURCES__
  39. #include <Resources.h>
  40. #endif
  41.  
  42. /*****************************************************************************/
  43.  
  44. static pascal void    PrintIdleProc( void );
  45. static DialogPtr    PrintingStatusDialog;
  46.  
  47. /*****************************************************************************/
  48.  
  49. /* eEdit specific stuff... */
  50.  
  51. extern void eTeDrawLine( eRec **hE, ChPos beginPos, Point location );
  52.  
  53. static void eTePrintGuts( eRec **hE, short *vNext, Rect *area, short lpp )
  54. {
  55.     eRec *pE;
  56.     short vLast, vFirst;
  57.     ChPos    startPos;
  58.     Point    location;
  59.     /* Rect    tRect; */
  60.     
  61.     HLock( (Handle )hE );
  62.     pE = *hE;
  63.     
  64.     if ( ( vFirst = *vNext ) < 0 )
  65.         vFirst = 0;
  66.  
  67.     vLast = vFirst - 1 + lpp;    /* lpp was: ( (*area).bottom - (*area).top ) / (*pE).vScale; */
  68.  
  69.     if ( vLast >= (*pE).bounds.v ) 
  70.     {    vLast = (*pE).bounds.v - 1;
  71.         *vNext = -1;
  72.     }
  73.     else
  74.         *vNext = vLast + 1;    /* for next time */
  75.  
  76.     /* EraseRect( &tRect ); */
  77.  
  78.     if ( vFirst < (*pE).bounds.v && vLast >= 0)
  79.  
  80.     {    location.h = (*area).left /* (*pE).leftMargin */ ;
  81.         location.v = (*area).top  /* (*pE).topMargin */  ;
  82.         startPos.h = 0;
  83.  
  84.         for ( startPos.v = vFirst;
  85.               startPos.v <= vLast;
  86.               location.v += (*pE).vScale, ++startPos.v )
  87.         {    eTeDrawLine( hE, startPos, location );
  88.         }
  89.         (**hE).curStyle = NOSTYLE;    /* gotta do to force first font/size/style in window */
  90.     }
  91.     HUnlock( (Handle )hE );
  92. }
  93.  
  94. static void headerPrepare( eRec **hE, short style )
  95. {
  96.     (**hE).curStyle = style;
  97.     TextFont( (**hE).style[style].tsFont );
  98.     TextFace( (**hE).style[style].tsFace );
  99.     TextSize( (**hE).style[style].tsSize );
  100.     /* RGBColor tsColor; */
  101.     PenMode(patCopy);PenSize(1,1);PenPat(&black);
  102. }
  103.  
  104. #define leftMargin(port) ((port)->portRect.left + 4)
  105.  
  106. static void dpyTab( short tabwidth )
  107. {
  108.     GrafPort *gPort;
  109.     short targetX;
  110.  
  111.     GetPort( &gPort );
  112.     targetX = leftMargin(gPort) + 
  113.         ( ( gPort->pnLoc.h - leftMargin(gPort) ) / tabwidth + 1 ) * tabwidth;
  114.     MoveTo( targetX, gPort->pnLoc.v );
  115. }
  116.  
  117. #define WAGspace (3)
  118.  
  119. static void    eTePrintPages( eRec **hE, TPPrPort printPort, Str255 nameString, short lastPage )
  120. {
  121.     Rect            area, frame;
  122.     OSErr            err;
  123.     short            tabwidth;
  124.     short            vNext = 0;
  125.     short             ePrintPage = 1;
  126.     short            lpp, lh;
  127.     long            time;
  128.     /* Str255        timeString, dateString, tStr; */
  129.     unsigned char   timeString[32];
  130.     unsigned char   dateString[64];
  131.     unsigned char   tStr[32];
  132.  
  133.     headerPrepare( hE, 1 );
  134.     tabwidth = CharWidth(' ') * (12);
  135.     GetDateTime( &time );
  136.     IUTimeString( time, 0, timeString );
  137.     IUDateString( time, abbrevDate, dateString );
  138.             
  139.     area = ((WindowPtr )printPort)->portRect;
  140.     ClipRect( &area );
  141.     InsetRect( &area, 4, 4 );    /* Just so no characters get clipped. */
  142.     lh = (**hE).vScale;
  143.     lpp = ( area.bottom - area.top ) / lh;
  144.     area.bottom = area.top + WAGspace + lpp * lh;
  145.     
  146.     frame = area;
  147.     InsetRect( &frame, -4, 0 );
  148.     area.top += lh + WAGspace;
  149.  
  150.     while( ePrintPage <= lastPage && ! (err = PrError()) )
  151.     {
  152.         PrOpenPage( printPort, nil );
  153.         if( ! (err = PrError()) )
  154.         {
  155.             headerPrepare( hE, 1 );
  156.             MoveTo( frame.left, frame.top + lh );            /* WAG */
  157.             Line(   frame.right - frame.left, 0 );
  158.             MoveTo( area.left, frame.top + (**hE).fontAscent );
  159.             DrawString( dateString );
  160.             dpyTab(tabwidth);
  161.             DrawString( timeString );
  162.             dpyTab(tabwidth);
  163.             DrawString( nameString );
  164.             dpyTab(tabwidth);
  165.             DrawString( "\ppage " );
  166.             NumToString( ePrintPage, &tStr );
  167.             DrawString( &tStr );
  168.  
  169.             eTePrintGuts( hE, &vNext, &area, lpp - 1 );
  170.             
  171.             headerPrepare( hE, 1 );
  172.             MoveTo( frame.left, frame.bottom );
  173.             LineTo( frame.right, frame.bottom);
  174.         }
  175.         PrClosePage( printPort );
  176.         if( vNext == -1 ) break;    /* Text didn't go to bottom of page so we're done */
  177.         ++ePrintPage;
  178.     }
  179. }
  180.  
  181. /*****************************************************************************/
  182. /* mostly generic stuff... */
  183.  
  184. /* This print-loop function is designed to be called under various situations.
  185. ** The big issue that it handles is finder printing.  If multiple documents
  186. ** are to be printed from the finder, the user should only see one job dialog
  187. ** for all the files.  (If a job dialog is shown for each file, how does the
  188. ** user know for which file the dialog is for?)  So, for situations where
  189. ** there is more than one file to be printed, call this code the first time
  190. ** with the firstJob boolean true.  Normally, the jobDlg boolean will also
  191. ** be true, except that under 7.0, you may be printing in the background.
  192. ** If this is the case, you don't want a job dialog for even the first file,
  193. ** and you should pass in false for the jobDlg boolean in this case.  For
  194. ** files 2-N, you should pass false for both booleans.  For regular application
  195. ** printing, you should pass true for both booleans, since the file is the
  196. ** first (only) file, and you are not in the background.
  197. **
  198. ** After calling this function to print a document, you need to call it
  199. ** again with a nil document handle.  The print record for the first (or only)
  200. ** document printed is preserved in a static variable.  This is so that the
  201. ** job dialog information can be passed on to documents 2-N in the print job.
  202. ** Calling this function with the document handle nil tells this function
  203. ** that you are done printing documents, and that the print record for the
  204. ** first job can be disposed of.
  205. */
  206.  
  207. OSErr    eTePrint( eRec **hE, Boolean jobDlg, Boolean firstJob, Str255 flnm)
  208. {
  209.     OSErr            err;
  210.     short            i, copies, keepResFile, fstPage, lstPage;
  211.     Boolean         do_init;
  212.     TPrStatus        status;
  213.     THPrint            prRecHndl;
  214.     TPPrPort        printPort;
  215.     GrafPtr            oldPort;
  216.     ControlHandle    proceedButton;
  217.     Rect             rct;
  218.  
  219.     static THPrint    prMergeHndl;
  220.  
  221.     if ( ! hE )
  222.     {    if ( prMergeHndl )
  223.         {    DisposHandle( (Handle )prMergeHndl );
  224.             prMergeHndl = nil;
  225.         }
  226.         return( noErr );
  227.     }
  228.  
  229.     PrintingStatusDialog = nil;
  230.  
  231.     if( ! (prRecHndl = (THPrint )NewHandle( sizeof( TPrint )) ) )
  232.     {    /* If we can't generate a print record handle, we are out of here. */
  233.         return(memFullErr);
  234.     }
  235.     if( (**hE).hPrint )
  236.     {    /* Get the document's print info into the print record handle. */
  237.         BlockMove( (Ptr )(*(**hE).hPrint), (Ptr )(*prRecHndl), sizeof( TPrint ) );
  238.         do_init = FALSE;
  239.     }
  240.     else
  241.     {    if (!((**hE).hPrint = (THPrint)NewHandle(sizeof(TPrint))))
  242.         {    /* If we can't generate a print record handle, we are out of here. */
  243.             DisposHandle( (Handle )prRecHndl );
  244.             return( memFullErr );
  245.         }
  246.         do_init = TRUE;
  247.     }
  248.  
  249.     GetPort(&oldPort);
  250.  
  251.     SetCursor(&qd.arrow);
  252.  
  253.     PrOpen();
  254.     err = PrError();
  255.  
  256.     if (!err) {
  257.         keepResFile = CurResFile();    /* some printers change CurResFile & we are being safe! */
  258.  
  259.         if( do_init )
  260.         {    PrintDefault(prRecHndl);        /* The document print record was never 
  261.             err = PrError();                ** initialized.  Now is is. */
  262.         }            
  263.         if( ! err )
  264.         {    PrValidate( prRecHndl );        /* Do this just 'cause Apple says so. */
  265.             err = PrError();
  266.         }
  267.         if( ! err )
  268.         {    if( jobDlg )                    /* User gets to click some buttons. */
  269.             {    if (!(PrJobDialog(prRecHndl))) err = userCanceledErr;
  270.                 else                           err = PrError();
  271.             }
  272.         }
  273.         if( ! err )
  274.         {    if( ! firstJob )
  275.             {    fstPage = (*prMergeHndl)->prJob.iFstPage;
  276.                 lstPage = (*prMergeHndl)->prJob.iLstPage;
  277.                 PrJobMerge(prMergeHndl, prRecHndl);
  278.                 (*prMergeHndl)->prJob.iFstPage = (*prRecHndl)->prJob.iFstPage = fstPage;
  279.                 (*prMergeHndl)->prJob.iLstPage = (*prRecHndl)->prJob.iLstPage = lstPage;
  280.                 err = PrError();
  281.             }
  282.         }
  283.  
  284.         if( ! err )
  285.         {    /* Put the defaulted/validated/jobDlg'ed print record in the doc. */
  286.             fstPage = (*prRecHndl)->prJob.iFstPage;
  287.             lstPage = (*prRecHndl)->prJob.iLstPage;
  288.             copies  = (*prRecHndl)->prJob.iCopies;
  289.             BlockMove((Ptr)(*prRecHndl), (Ptr)(*(**hE).hPrint), sizeof(TPrint));
  290.             /* Setup the proceed/pause/cancel dialog with the document name. */
  291.             ParamText( flnm, nil, nil, nil);
  292.             PrintingStatusDialog = GetNewDialog( rPrStatusDlg, nil, (WindowPtr )-1 );
  293.             if (PrintingStatusDialog)
  294.             {
  295. #ifndef THINK_PRE_5
  296.                 GetDItem(PrintingStatusDialog, 1, &i, (Handle *)&proceedButton, &rct);
  297. #else
  298.                 GetDItem(PrintingStatusDialog, 1, &i, &proceedButton, &rct);
  299. #endif
  300.                 HiliteControl(proceedButton, 255);
  301.                 /* Hook in the proceed/pause/cancel dialog. */
  302.                 (*prRecHndl)->prJob.pIdleProc = PrintIdleProc;
  303.             }
  304.             UseResFile( keepResFile );    /* some printers change CurResFile & we are being safe! */
  305.  
  306.             for( i = 1; i <= copies && ! err; ++i )
  307.             {
  308.                 printPort = PrOpenDoc(prRecHndl, nil, nil);
  309.                 if ( ! ( err = PrError() ) ) eTePrintPages( hE, printPort, flnm, lstPage );
  310.                 PrCloseDoc( printPort );
  311.             }
  312.         }
  313.         else if( do_init )
  314.         {    DisposHandle( (Handle)(**hE).hPrint );
  315.             (**hE).hPrint = NULL;
  316.         }
  317.  
  318.         if ((!err) && ((*prRecHndl)->prJob.bJDocLoop == bSpoolLoop) && (!(err = PrError())) )
  319.         {
  320.             PrPicFile(prRecHndl, nil, nil, nil, &status);
  321.             err = PrError();
  322.         }
  323.     }
  324.  
  325.     if (firstJob) prMergeHndl = prRecHndl;
  326.     else          DisposHandle( (Handle )prRecHndl );
  327.  
  328.     if( PrintingStatusDialog ) DisposDialog( PrintingStatusDialog );
  329.  
  330.     PrClose();
  331.     SetPort(oldPort);
  332.  
  333.     return(err);
  334. }
  335.  
  336. /*****************************************************************************/
  337.  
  338. /* PrintIdleProc will handle events in the 'Printing Status Dialog' which
  339. ** gives the user the option to 'Proceed', 'Pause', or 'Cancel' the current
  340. ** printing job during print time.
  341. **
  342. ** The buttons:
  343. **        1: Proceed
  344. **        2: Pause
  345. **        3: Cancel 
  346. */
  347.  
  348. pascal void        PrintIdleProc(void)
  349. {
  350.     Boolean                button, paused;
  351.     ControlHandle        pauseButton, proceedButton;
  352.     DialogPtr            aDialog;
  353.     EventRecord            anEvent;
  354.     GrafPtr                oldPort;
  355.     Rect                 rct;
  356.     short                item, itemType;
  357.  
  358.     if( ! PrintingStatusDialog ) return;
  359.     
  360.     GetPort( &oldPort );
  361.  
  362. #ifndef THINK_PRE_5
  363.     GetDItem( PrintingStatusDialog, 1, &itemType, (Handle *)&proceedButton, &rct );
  364.     HiliteControl( proceedButton, 255 );
  365.     GetDItem( PrintingStatusDialog, 2, &itemType, (Handle *)&pauseButton, &rct );
  366. #else
  367.     GetDItem( PrintingStatusDialog, 1, &itemType, &proceedButton, &rct );
  368.     HiliteControl( proceedButton, 255 );
  369.     GetDItem( PrintingStatusDialog, 2, &itemType, &pauseButton, &rct );
  370. #endif
  371.  
  372.     paused = false;
  373.     do {
  374.         if( GetNextEvent( (mDownMask + mUpMask + updateMask), &anEvent ) ) {
  375.             if( PrintingStatusDialog != FrontWindow () )
  376.                 SelectWindow( PrintingStatusDialog );
  377.  
  378.             if ( IsDialogEvent( &anEvent ) ) {
  379.                 button = DialogSelect( &anEvent, &aDialog, &item );
  380.  
  381.                 if ( (button) && (aDialog == PrintingStatusDialog) ) {
  382.                     switch (item) {
  383.                         case 1:
  384.                             HiliteControl( pauseButton, 0 );        /* Enable PAUSE    */
  385.                             HiliteControl( proceedButton, 255 );    /* Disable PROCEED */
  386.                             paused = false;
  387.                             break;
  388.                         case 2:
  389.                             HiliteControl( pauseButton, 255 );    /* Disable PAUSE  */
  390.                             HiliteControl( proceedButton, 0 );    /* Enable PROCEED */
  391.                             paused = true;
  392.                             break;
  393.                         case 3:
  394.                             PrSetError( iPrAbort );               /* CANCEL printing */
  395.                             paused = false;
  396.                             break;
  397.                     }
  398.                 }
  399.             }
  400.         }
  401.     } while( paused != false ); 
  402.  
  403.     SetPort( oldPort );
  404. }
  405.  
  406. /*****************************************************************************/
  407.  
  408. OSErr    PageSetupDialog( eRec **hE )
  409. {
  410.     OSErr        err;
  411.     Boolean     do_init;
  412.     THPrint        prRecHndl;
  413.  
  414.     SetCursor( &qd.arrow );
  415.     
  416.     if( ! ( prRecHndl = (THPrint )NewHandle( sizeof( TPrint )) ) )
  417.     {    /* If we can't generate a print record handle, we are out of here. */
  418.         return( memFullErr );
  419.     }
  420.     if( (**hE).hPrint )
  421.     {    /* Get the document's print info into the print record handle. */
  422.         BlockMove( (Ptr )(*(**hE).hPrint), (Ptr )(*prRecHndl), sizeof( TPrint ) );
  423.         do_init = FALSE;
  424.     }
  425.     else
  426.     {    if( ! ( (**hE).hPrint = (THPrint )NewHandle( sizeof( TPrint )) ) )
  427.         {    /* If we can't generate a print record handle, we are out of here. */
  428.              err = memFullErr;
  429.              goto pguperr;
  430.         }
  431.         do_init = TRUE;
  432.     }
  433.  
  434.     PrOpen();
  435.  
  436.     if( ! (err = PrError()) )
  437.  
  438.     {    if( do_init ) PrintDefault( prRecHndl );
  439.         else          PrValidate( prRecHndl );
  440.         if( ! (err = PrError()) )
  441.         {    if( PrStlDialog(prRecHndl) )
  442.             {    BlockMove((Ptr)*prRecHndl, (Ptr)(*(**hE).hPrint), sizeof(TPrint));
  443.                 /* (*frHndl)->doc.printRecValid  = true; */
  444.                 /* (*frHndl)->fileState.docDirty = true; */
  445.             }
  446.             else
  447.             {    err = userCanceledErr;
  448.                 if( do_init )
  449.                 {    DisposHandle((Handle)(**hE).hPrint);
  450.                     (**hE).hPrint = NULL;
  451.                 }
  452.             }
  453.         }
  454.     }
  455.     PrClose();
  456.  
  457. pguperr:
  458.     DisposHandle( (Handle)prRecHndl );
  459.     return( err );
  460. }
  461.  
  462. /* end of os_mac_Print.c */
  463.